#include "sevensegmentview.hpp"
#include "ui_sevensegmentview.h"

SevenSegmentView::SevenSegmentView(RegisterView *regView, QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::SevenSegmentView)
{
    ui->setupUi(this);
    this->bank = 0;
    this->address = 0;
    this->regView = regView;
    diagramScene = new DiagramScene();
    ui->gv_lcd->setScene(diagramScene);

    qreal startX = 0;
    qreal startY = 0;
    qreal x = 10;
    qreal y = 10;
    qreal width = 100;
    qreal space = 2;

    QPointF pa1 = QPointF(startX + space, startY - space);
    QPointF pa2 = QPointF(startX + space + x, startY - space - y);
    QPointF pa3 = QPointF(startX + space + width - x, startY - space - y);
    QPointF pa4 = QPointF(startX + space + width, startY - space);
    QPointF pa5 = QPointF(startX + space + width - x, startY - space + y);
    QPointF pa6 = QPointF(startX + space + x, startY - space + y);

    QPointF pb1 = QPointF(startX + 3*space + width, startY + space);
    QPointF pb2 = QPointF(startX + 3*space + width + x, startY + space + y);
    QPointF pb3 = QPointF(startX + 3*space + width + x, startY + space + width - y);
    QPointF pb4 = QPointF(startX + 3*space + width, startY + space + width);
    QPointF pb5 = QPointF(startX + 3*space + width - x, startY + space + width - y);
    QPointF pb6 = QPointF(startX + 3*space + width - x, startY + space + y);

    QPointF pc1 = QPointF(startX + 3*space + width, startY + 3*space + width);
    QPointF pc2 = QPointF(startX + 3*space + width + x, startY + 3*space + width + y);
    QPointF pc3 = QPointF(startX + 3*space + width + x, startY + 3*space + 2*width - y);
    QPointF pc4 = QPointF(startX + 3*space + width, startY + 3*space + 2*width);
    QPointF pc5 = QPointF(startX + 3*space + width - x, startY + 3*space + 2*width - y);
    QPointF pc6 = QPointF(startX + 3*space + width - x, startY + 3*space + width + y);

    QPointF pd1 = QPointF(startX + space, startY + 5*space + 2*width);
    QPointF pd2 = QPointF(startX + space + x, startY + 5*space + 2*width - y);
    QPointF pd3 = QPointF(startX + space + width - x, startY + 5*space + 2*width - y);
    QPointF pd4 = QPointF(startX + space + width, startY + 5*space + 2*width);
    QPointF pd5 = QPointF(startX + space + width - x, startY + 5*space + 2*width + y);
    QPointF pd6 = QPointF(startX + space + x, startY + 5*space + 2*width + y);

    QPointF pe1 = QPointF(startX - space, startY + 3*space + width);
    QPointF pe2 = QPointF(startX - space + x, startY + 3*space + width + y);
    QPointF pe3 = QPointF(startX - space + x, startY + 3*space + 2*width - y);
    QPointF pe4 = QPointF(startX - space, startY + 3*space + 2*width);
    QPointF pe5 = QPointF(startX - space - x, startY + 3*space + 2*width - y);
    QPointF pe6 = QPointF(startX - space - x, startY + 3*space + width + y);

    QPointF pf1 = QPointF(startX - space, startY + space);
    QPointF pf2 = QPointF(startX - space + x, startY + space + y);
    QPointF pf3 = QPointF(startX - space + x, startY + space + width - y);
    QPointF pf4 = QPointF(startX - space, startY + space + width);
    QPointF pf5 = QPointF(startX - space - x, startY + space + width - y);
    QPointF pf6 = QPointF(startX - space - x, startY + space + y);

    QPointF pg1 = QPointF(startX + space, startY + 2*space + width);
    QPointF pg2 = QPointF(startX + space + x, startY + 2*space + width - y);
    QPointF pg3 = QPointF(startX + space + width - x, startY + 2*space + width - y);
    QPointF pg4 = QPointF(startX + space + width, startY + 2*space + width);
    QPointF pg5 = QPointF(startX + space + width - x, startY + 2*space + width + y);
    QPointF pg6 = QPointF(startX + space + x, startY + 2*space + width + y);

    QVector<QPointF> vectorA;
    vectorA.append(pa1);
    vectorA.append(pa2);
    vectorA.append(pa3);
    vectorA.append(pa4);
    vectorA.append(pa5);
    vectorA.append(pa6);
    vectorA.append(pa1);

    QVector<QPointF> vectorB;
    vectorB.append(pb1);
    vectorB.append(pb2);
    vectorB.append(pb3);
    vectorB.append(pb4);
    vectorB.append(pb5);
    vectorB.append(pb6);
    vectorB.append(pb1);

    QVector<QPointF> vectorC;
    vectorC.append(pc1);
    vectorC.append(pc2);
    vectorC.append(pc3);
    vectorC.append(pc4);
    vectorC.append(pc5);
    vectorC.append(pc6);
    vectorC.append(pc1);

    QVector<QPointF> vectorD;
    vectorD.append(pd1);
    vectorD.append(pd2);
    vectorD.append(pd3);
    vectorD.append(pd4);
    vectorD.append(pd5);
    vectorD.append(pd6);
    vectorD.append(pd1);

    QVector<QPointF> vectorE;
    vectorE.append(pe1);
    vectorE.append(pe2);
    vectorE.append(pe3);
    vectorE.append(pe4);
    vectorE.append(pe5);
    vectorE.append(pe6);
    vectorE.append(pe1);

    QVector<QPointF> vectorF;
    vectorF.append(pf1);
    vectorF.append(pf2);
    vectorF.append(pf3);
    vectorF.append(pf4);
    vectorF.append(pf5);
    vectorF.append(pf6);
    vectorF.append(pf1);

    QVector<QPointF> vectorG;
    vectorG.append(pg1);
    vectorG.append(pg2);
    vectorG.append(pg3);
    vectorG.append(pg4);
    vectorG.append(pg5);
    vectorG.append(pg6);
    vectorG.append(pg1);

    segmentA = new QGraphicsPolygonItem();
    segmentB = new QGraphicsPolygonItem();
    segmentC = new QGraphicsPolygonItem();
    segmentD = new QGraphicsPolygonItem();
    segmentE = new QGraphicsPolygonItem();
    segmentF = new QGraphicsPolygonItem();
    segmentG = new QGraphicsPolygonItem();
    segmentDot = new QGraphicsEllipseItem(width + 1.5*x, 2*width - y/2 + 4*space, 1.5*x, 1.5*y);

    segmentA->setPolygon(QPolygonF(vectorA));
    segmentB->setPolygon(QPolygonF(vectorB));
    segmentC->setPolygon(QPolygonF(vectorC));
    segmentD->setPolygon(QPolygonF(vectorD));
    segmentE->setPolygon(QPolygonF(vectorE));
    segmentF->setPolygon(QPolygonF(vectorF));
    segmentG->setPolygon(QPolygonF(vectorG));

    diagramScene->addItem(segmentA);
    diagramScene->addItem(segmentB);
    diagramScene->addItem(segmentC);
    diagramScene->addItem(segmentD);
    diagramScene->addItem(segmentE);
    diagramScene->addItem(segmentF);
    diagramScene->addItem(segmentG);
    diagramScene->addItem(segmentDot);

    ui->gv_lcd->scale(0.5, 0.5);
    ui->gv_lcd->setRenderHint(QPainter::Antialiasing, true);
}


SevenSegmentView::~SevenSegmentView()
{
    delete segmentA;
    delete segmentB;
    delete segmentC;
    delete segmentD;
    delete segmentE;
    delete segmentF;
    delete segmentG;
    delete segmentDot;
    delete diagramScene;
    delete ui;
}


void SevenSegmentView::changeEvent(QEvent *e)
{
    QDockWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}


void SevenSegmentView::on_cb_ConnectTo_Bank0_currentIndexChanged(int index)
{
    switch(index)
    {
    case 1:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
	this->bank = 0;
	break;
    default:
	this->bank = 2;
	break;
    }
    this->address = index;
    Register tempReg;
    tempReg.setValue(regView->getValue(this->bank, this->address));
    show(&tempReg);
}


void SevenSegmentView::on_cb_ConnectTo_Bank1_currentIndexChanged(int index)
{
    this->bank = 1;
    this->address = index;
    Register tempReg;
    tempReg.setValue(regView->getValue(this->bank, this->address));
    show(&tempReg);
}


void SevenSegmentView::on_rad_Bank0_toggled(bool state)
{
    if (state)
	on_cb_ConnectTo_Bank0_currentIndexChanged(ui->cb_ConnectTo_Bank0->currentIndex());
}


void SevenSegmentView::on_rad_Bank1_toggled(bool state)
{
    if (state)
	on_cb_ConnectTo_Bank1_currentIndexChanged(ui->cb_ConnectTo_Bank1->currentIndex());
}


void SevenSegmentView::on_rad_Special_toggled(bool state)
{
    if (state)
	on_cb_ConnectTo_Special_currentIndexChanged(ui->cb_ConnectTo_Special->currentIndex());
}


void SevenSegmentView::on_cb_ConnectTo_Special_currentIndexChanged(int index)
{
    switch (index)
    {
    case 0:
	this->bank = -1;
	this->address = -1;
	break;

    case 1:
	this->bank = -1;
	this->address = -2;
	break;
    }

    Register tempReg;
    tempReg.setValue(regView->getValue(this->bank, this->address));
    show(&tempReg);
}


void SevenSegmentView::onRegisterChanged(Register *reg)
{
    if (reg->getBank() == this->bank && reg->getAddress() == this->address)
    {
	// Create 7-Segment Output
	show(reg);
    }
}


void SevenSegmentView::show(Register *reg)
{
    if (reg->getValue() < 0)
	return;
    int value = reg->getValue();
    if (reg->getAddress() == -2 && reg->getBank() == -1)
	value++;
    // Renew LCD Displays
    ui->lcd_binary->display(value);
    ui->lcd_decimal->display(value);
    ui->lcd_hex->display(value);

    if(reg->isSet(0))
    {
	segmentA->setBrush(Qt::green);
    }
    else
    {
	segmentA->setBrush(Qt::white);
    }

    if(reg->isSet(1))
    {
	segmentB->setBrush(Qt::green);
    }
    else
    {
	segmentB->setBrush(Qt::white);
    }

    if(reg->isSet(2))
    {
	segmentC->setBrush(Qt::green);
    }
    else
    {
	segmentC->setBrush(Qt::white);
    }

    if(reg->isSet(3))
    {
	segmentD->setBrush(Qt::green);
    }
    else
    {
	segmentD->setBrush(Qt::white);
    }

    if(reg->isSet(4))
    {
	segmentE->setBrush(Qt::green);
    }
    else
    {
	segmentE->setBrush(Qt::white);
    }

    if(reg->isSet(5))
    {
	segmentF->setBrush(Qt::green);
    }
    else
    {
	segmentF->setBrush(Qt::white);
    }

    if(reg->isSet(6))
    {
	segmentG->setBrush(Qt::green);
    }
    else
    {
	segmentG->setBrush(Qt::white);
    }

    if(reg->isSet(7))
    {
	segmentDot->setBrush(Qt::green);
    }
    else
    {
	segmentDot->setBrush(Qt::white);
    }
}
